﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>RegExMatch</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="../css/commands.css" rel="stylesheet" type="text/css">
<link href="../css/print.css" rel="stylesheet" type="text/css" media="print">
</head>
<body>
<h1>RegExMatch() <span class="small65">[v1.0.45+]</span></h1>



<p>确定一个字符串中所包含的匹配模式 (即：正则表达式)。</p>

<p class="CommandSyntax">FoundPos := RegExMatch(Haystack, NeedleRegEx [, UnquotedOutputVar = &quot;&quot;, StartingPosition = 1])</p>

<h3>参数 </h3>

<table bordercolor="#c0c0c0" cellspacing="0" cellpadding="3" width="100%" border="1"><tbody>
    <tr>
      <td width="15%">FoundPos</td>

      <td width="85%">RegExMatch() 返回从源字符串 <em>Haystack </em>最左边开始找到的第一个匹配 <em>NeedleRegEx </em>模式的位置。首字符的位置是 1 。要是在字符串中没有找到匹配模式的时候就会返回 0。如果出现了错误 (比如：<em>正则表达式 </em><em>NeedleRegEx</em><em>&#160;</em>的语法错误)，它将会返回一个空的字符串和 ErrorLevel 。ErrorLevel 将是 <a href="#ErrorLevel">下面</a> 值中的一个，包括 0。 </td>
    </tr>

    <tr>
      <td>Haystack</td>

      <td>源字符串。</td>
    </tr>

    <tr>
      <td>NeedleRegEx</td>

      <td>这种匹配模式是和 Perl 兼容的正则表达式 (PCRE) 。如果有必要的话，可以在正则表达式前加上 <a href="#Options">选项</a> ，并以 &quot;)&quot; 结束。例如：这个匹配模式 &quot;<font color="#ff0000">i)</font>abc.*123&quot; 将匹配不区分大小写的 &quot;abc&quot; ，中间可以是任何字符，并以 123 结尾的模式进行搜索。要是没有 选项 ，这个 &quot;)&quot; 是可选的，例如： &quot;)abc&quot; 就等同于 &quot;abc&quot; 。 </td>
    </tr>

    <tr>
      <td><span class="CommandSyntax">UnquotedOutputVar</span></td>

      <td>
        <p><strong>形式1 (默认)：</strong><em>OutputVar </em>是 unquoted 的一个变量名，它将存储 <em>Haystack </em>中符合匹配模式的那一部分字符串。如果没有找到符合这个模式的子串 (那么，RegExMatch() 将返回 0 )，而输出变量和所有的数组元素将被置为空。</p>

        <p>如果在 <em>NeedleRegEx</em> 中包含 <a href="../misc/RegEx-QuickRef.htm#subpat">捕捉子模式</a> ，那么它们将存储在以 <em>OutputVar</em> 为基变量的 <a href="../misc/Arrays.htm">数组</a> 里。例如：输出的变量名是 <em>Match</em> ，那它第一个能匹配子模式的子串将存储在 <em>Match1</em> ，第二个存储在 <em>Macth2</em> ，等等。有一个例外是 <a href="#NamedSubPat">命名子模式</a> ：它用名字代替了数字的形式来存储。例如：这种模式 <em>(?P&lt;Year&gt;\d{4})</em> ，会把输出的子串存储在 <em>MatchYear</em> 里面。如果没有任何字符串 (或者此函数返回的值是 0 )，那么这一输出变量置为空。</p>

        <p>在 <a href="../Functions.htm">函数</a> 中创建一个全局变量的数组来替代局部变量，就要在使用前 <a href="../Functions.htm#Global">声明</a> 数组名 (比如刚才的 Match ) 为全局变量。</p>

        <p><strong>形式2 (位置 – 长度)：</strong>若以 P 开头的正则表达式，比如，&quot;<font color="#ff0000">P)</font>abc.*123&quot;，则完全匹配正则表达式的字符串的 <em>长度</em> 将存储在 <em>OutputVar</em> 里 (没有匹配到，长度就是 0 )。如果现在使用了 <a href="../misc/RegEx-QuickRef.htm#subpat">捕捉子模式</a> ，就会有两个数组 <em>OutputOvarPos</em> 和 <em>OutputVarLen</em> 分别存储匹配到的字符串的位置和长度。例如：若基变量名为 <em>Match</em> ，则符合模式的第一个子串的位置存储在 <em>MatchPos1</em> ，长度存储在<em> MatchLen1</em> (没到匹配到任何子串则全部返回 0 ，函数值也会为 0 )。仍有一个例外，就是 <a href="#NamedSubPat">命名子模式</a>：它将存储名用名字替代了数字 (比如，<em>MatchPosYear</em> 和 <em>MatchLenYear</em> )。</p>
      </td>
    </tr>

    <tr>
      <td>StartingPosition</td>

      <td>
        <p>如果省略 <em>StartingPostion</em> 的值，它会默认为 1 (从源字符串 <em>Haystack</em> 的第一个字符开始)。另外，设置为 2 则以第二个字符开始，值为 3 就从第三个开始，依次类推。如果 <em>StartingPostion</em> 的值超出了 <em>Haystack</em> 的长度范围，则函数返回为 0 ，变量值为空。</p>

        <p>如果 <em>StartingPostion</em> 的值小于1，函数会认为是从 <em>Haystack</em> 的末尾处开始。例如：0 就是倒数一个字符的位置，-1 就是倒数第二个字符，依次类推。如果 <em>StartingPostion</em> 超过了 <em>Haystack</em> 最左边的位置，它就会搜索整个 <em>Haystack</em> 。</p>

        <p>无论 <em>StartinPostion</em> 的值是什么，函数返回的值都是根据 <em>Haystack</em> 的第一个字符所确定的。例如：&quot;123abc789” 中 &quot;abc” 的位置总是 4 。</p>
      </td>
    </tr>
  </tbody></table>

<h3><a name="ErrorLevel"></a>ErrorLevel</h3>

<p><a href="../misc/ErrorLevel.htm">ErrorLevel</a> 的值是下面中的一个:</p>

<ul>
  <li>0, 表示没发现错误。 </li>

  <li>一个有如下格式的字符串：<em>Complie error N at offset M: description.</em> 在这个字符串里，<em>N</em> 是 PCRE ( Perl 兼容正则表达式 ) 的错误值，<em>M</em> 是正则表达式中出现错误的位置，<em>description</em> 是描述这个错误的文本信息。 </li>

  <li>一个负数，是指在 <em>执行</em> 正则表达式过程中出现的错误。尽管这种错误非常罕见，如这些情况就容易出现这种错误：”太多的空匹配“ (-22)，”递归太深“ (-21)，”太到匹配极限“ (-8)。如果出现了这些错误，就试着重新写更严格的正则表达式，如用 ? , + 或者用有限制的方式，如 {0,3} 来取代 * 。 </li>
</ul>

<h3>选项 <font color="#ff0000">( 区分大小写 )</font></h3>

<p>在正则表达式之前加上 0 个或者多个选项并以右括号结束。例如：模式 &quot;im)abc” 将搜索多行中不区分大小写的 <em>abc</em> ，若没有选项可以省略圆括号。尽管这将原来的语法打断，但是它不需要新的前分割符 (比如右斜杠)，因此没有必要转换模式内的分割符。另外，由于使用了选项，函数性能有所提升。</p>

<table bordercolor="#c0c0c0" cellspacing="0" cellpadding="3" width="100%" border="1"><tbody>
    <tr>
      <td><strong>i</strong></td>

      <td>不区分大小写。</td>
    </tr>

    <tr>
      <td><strong>m</strong></td>

      <td>
        <p>多行是指由多个单行 (有换行符) 所组成的一个集合 (它包括换行符) 。但在下列情况会有所改变：</p>

        <p>1) 弯折符号 (^) 在所有行内匹配 -- 总是从源字符串开头的地方开始匹配 (但不是匹配源字符串 <em>Haystack</em> 中换行 <em>靠后</em> 的地方)。</p>

        <p>2) 美元符号 ($) 在源字符串中任意换行符之前匹配 (也就是说，它总是匹配每行靠近结尾的地方)。</p>

        <p>例如：源字符串是 &quot;xyz`r`nabc&quot; 中的 abc 要用模式 &quot;m)^abc$&quot; 来精确匹配。</p>

        <p>如果选项是 &quot;D&quot;，它就将会忽略当前的 &quot;m&quot;。 </p>
      </td>
    </tr>

    <tr>
      <td><strong>s</strong></td>

      <td>该选项会使点 (.) 能匹配一行内所有的字符 (通常不会换行符后的) 。如果换行符是默认的 CRLF (`r`n) ，就要用两个点去匹配它 (而不是一个点)。无论这个选项如何，[^a] 总是匹配换行符。</td>
    </tr>

    <tr>
      <td><strong>x</strong></td>

      <td>忽略模式中空白字符类。如字符 `n 和 `t 这类的字符将被在正则表达式中的忽略，这些字符都是出现在正则表达式中 (与此相反，使用 \n 和 \t 之类的字符就不会被正则表达式忽略)。<strong>x</strong> 选项也是一个复杂的模式。然而，这种模式必须遵循这个条件： <em>只能</em> 应用在数据字符中；空白字符也许不会出现特殊的序列，如 (?(。</td>
    </tr>

    <tr>
      <td><strong>A</strong></td>

      <td>强制将匹配模式固定；也就是说，它只能从源字符串的第一个字符开始匹配。大数情况下，和 &quot;^&quot; 的功能一样。</td>
    </tr>

    <tr>
      <td><strong>D</strong></td>

      <td>强制用 ($) 的方式来从靠近源字符串末尾的地方开始匹配，即使源字符串以的换行符结尾的。没有这个选项时，$ 就只能匹配换行符 (如果有的话) 前的字符了。注意：这个选项会让 &quot;m&quot; 选项不起作用。</td>
    </tr>

    <tr>
      <td><strong>J</strong></td>

      <td>允许重复 <a href="#NamedSubPat">命名子模式</a> 。这是一个很有用的模式，它在一组相同命名子模式下也能够匹配。注意：如果有多个实例命名去匹配字符串的话，就只有最左边的那个命名才会被存储 (变量名不区分大小写)。 </td>
    </tr>

    <tr>
      <td><strong>U</strong></td>

      <td>非贪婪的。只有在绝对必要的情况下才会使用量词 *+?{} ，并将剩下的部分提供给下一个模式。当 &quot;U&quot; 选项无效时，可以通过一个问号作为量词进行非贪婪匹配。相反地，当 &quot;U&quot; 选项有效，问号就会进行贪婪搜索。</td>
    </tr>

    <tr>
      <td><strong>X</strong></td>

      <td>PCRE 扩展。它使 PCRE 不完全符合 Perl 的正则表达式。目前，仅仅只有一个这样的特点，那就是在模式中的任何的反斜杠后加一个字符就没有特殊的意义并导致匹配失败和设置 ErrorLevel 相应的值。这个选项帮助保留未使用的反斜杠序列供以后使用。没有这个选项，反斜杠后的字符就会看成一般的字符而没有特殊的意义 (例如：\g 和 g 都被认为是字母 g )。不论此选项怎样，非字母反斜杠序列都没有特别的意义，它将总是认为是普通的字符 (例如：\/ 和 / 都被认为是 / )。</td>
    </tr>

    <tr>
      <td><strong>P</strong></td>

      <td>位置模式。它会使函数 RegExMatch() 产生匹配到的子串的位置和长度。更详细的了解，请看上面的 <a href="#PosMode">输出变量</a>。</td>
    </tr>

    <tr>
      <td><strong>S</strong></td>

      <td>研究模式可以提高函数的性能。当匹配模式比较复杂或者被重复执行很多次的情况下，这个选项很有用。它会让匹配模式存储在高速缓存中，以便下次使用，通过这种方法来提高了正则表达式的性能。</td>
    </tr>

    <tr>
      <td><strong>`n</strong></td>

      <td>替换默认的换行符 (`r`n) 为符合 UNIX 系统的标准的 (`n)。所选择的换行符会影响到 <a href="$RegEx-QuickRef.htm">anchors (^ and $)</a> 和 <a href="$RegEx-QuickRef-0.htm">dot/period pattern</a> 。</td>
    </tr>

    <tr>
      <td><strong>`r</strong></td>

      <td>替换默认的换行符 (`r`n) 为符合 Windwos 标准的 (`r)。</td>
    </tr>

    <tr>
      <td><strong>`a</strong></td>

      <td>在 1.0.46.06+ 的版本中，`a 看作是换行符，也就是指这些符号，`r，`n，`r`n，`v/VT/vertical tab/chr(0xB)，`f/FF/formfeed/chr(0xC)，and NEL/next-line/chr(0x85)。在 1.0.47.05+ 的版本中，换行符被限制为 CR，LF 和 CRLF 为 (*ANYCRLF) ，在选项后的正则表达式之前大写；例如： im)(*ANYCRLF)^abc$</td>
    </tr>
  </tbody></table>

<p>注意：可用空格和 Tab 随意的隔开每个选项。</p>

<h3>性能</h3>

<p>如果从一个较长的字符串中搜索一个简单的子串，请使用 <a href="../Functions.htm#InStr">InStr()</a> 函数，因为它比 RegExMatch() 更有效率。</p>

<p>为了提高性能，它将最近使用的 100 个正则表达式缓存在内存里 (在编译的时候)。</p>

<p>当一个正则表达式重复使用的情况下，使用 <a href="#Study">S 选项</a> 来提高性能。(比如在 loop 循环中)</p>

<h3>注意</h3>

<p><a name="NamedSubPat"></a>一个命名子模式都有一个名字，如上文模式 <em>(?P&lt;Year&gt;\d{4})</em> 中的 <em>Year</em> 。这些名字可能包括多达 32 个字母、数字和下划线。虽然这些命名子模式都是通过数字在对正则表达式本身的操作 (如：<a href="RegExReplace.htm#BackRef">向后引用</a>)，结果是仅仅用名字存储 <a href="#Array">输出数组</a>，而不是用数字。例如 &quot;Year&quot; 是第一个名字，把匹配到的子串存储在 <em>OutputVarYear</em> 里，但是 <em>OutputVar1</em> 的值是没有改变 (它将保留以前的值，如果有的话)。如果是 <a href="../misc/RegEx-QuickRef.htm#subpat">非命名子模式</a> 的 &quot;Year&quot; ，它将匹配到的子串存储在 <em>OutputVar2</em> 里，而不是 <em>OutputVar1</em> 里。</p>

<p>大多数的字符串 ( 像 abc123 ) 就能用一般的字符来匹配。而匹配像 <strong>\.*?+[{|()^$</strong> 这样被保护的字符就要在其前面加是一个反斜杠。比如：<strong>\.</strong> 代表一个点，<strong>\\</strong> 代表一个反斜杠。转义符可避免使用 \Q…\E。比如 \QLiteral Text\E。</p>

<p>在正则表达式中，一些特殊的字符，如制表符和换行符就用重音符号 (`) 或反斜杠 (\) 来表示。例如：`t is the same as \t 。</p>

<p>如学习正则表达式的基础 (或者重新记忆一下正则表达式的语法) ，请看 <a href="../misc/RegEx-QuickRef.htm">RegEx Quick Reference</a>。</p>

<p>AutoHotKey 所使用的正则表达式是来自于 <a href="http://www.pcre.org">www.pcre.org</a> 的兼容 Perl 语言的正则表达式。</p>

<h3>相关命令</h3>

<p><a href="RegExReplace.htm">RegExReplace()</a>, <a href="../misc/RegEx-QuickRef.htm">RegEx Quick Reference</a>, <a href="../Functions.htm#InStr">InStr()</a>, <a href="IfInString.htm">IfInString</a>, <a href="StringGetPos.htm">StringGetPos</a>, <a href="../Functions.htm#SubStr">SubStr()</a>, <a href="SetTitleMatchMode.htm#RegEx">SetTitleMatchMode RegEx</a>, <a href="http://www.autohotkey.com/forum/topic16164.html">Global matching and Grep (forum link)</a></p>

<p>Common sources of text data: <a href="FileRead.htm">FileRead</a>, <a href="UrlDownloadToFile.htm">UrlDownloadToFile</a>, <a href="../misc/Clipboard.htm">Clipboard</a>, <a href="GuiControls.htm#Edit">GUI Edit controls</a></p>

<h3>示例</h3>

<pre class="NoIndent">FoundPos := RegExMatch(&quot;xxxabc123xyz&quot;, &quot;abc.*xyz&quot;)  <em>; 返回值 4，它就是匹配到的位置。</em>
FoundPos := RegExMatch(&quot;abc123123&quot;, &quot;123$&quot;)  <em>; 返回值 7，因为 $ 要求从靠近最后的字符处开始匹配。</em>
FoundPos := RegExMatch(&quot;abc123&quot;, &quot;i)^ABC&quot;)  <em>; 返回值 1，因为是要求从第一个字符处开始匹配，而且不区分大小写。</em>
FoundPos := RegExMatch(&quot;abcXYZ123&quot;, &quot;abc(.*)123&quot;, SubPat)  <em>;返回 1 并且 SubPat1 的值是 &quot;XYZ&quot;。</em>
FoundPos := RegExMatch(&quot;abc123abc456&quot;, &quot;abc\d+&quot;, &quot;&quot;, 2)  <em>; 返回值 7 ，由于它是从第二个字符开始匹配的。</em>

<em>; 更多正则表达式的例子，请看 <a href="../misc/RegEx-QuickRef.htm">RegEx Quick Reference</a>.</em></pre>

</body>
</html>